<template>
  <div class="pop-wrapper" ref="popup">
    <div class="mask" ref="mask"></div>
    <svg
      x="0px"
      y="0px"
      viewBox="0 0 1562.4 752.6"
      style="enable-background: new 0 0 1562.4 752.6"
      xml:space="preserve"
    >
      <rect
        x="23.1"
        y="19.3"
        class="st0"
        width="1517"
        height="714"
        ref="rect1"
      />
      <rect x="2.6" y="2.3" class="st1" width="1558" height="748" ref="rect2" />
    </svg>
    <div
      :class="['pop-wrapper-content', desShow ? '' : 'content-noDes']"
      ref="popWrapper"
    >
      <div
        :class="['player-wrapper', desShow ? '' : 'no-border']"
        ref="content"
      >
        <video
          ref="player"
          class="player"
          id="video-player"
          :src="content"
          controls
          loop
          :muted="muted"
          v-if="isVideo"
        ></video>
        <component
          :is="content"
          v-if="!!isComp"
          ref="popupComponent"
          :style="scaleFun"
        ></component>
        <div
          class="content"
          v-if="!!isImage"
          :style="`background:url(${content})`"
        ></div>
      </div>
      <div class="describe" :key="num" v-if="desShow">
        <txt
          class="title HYLXTJ"
          :value="title"
          :params="{
            animateDuration: 0.5,
            animateType: 'waveSmall'
          }"
          ref="title"
        ></txt>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<txt
          ref="describe"
          class="txt"
          :value="describe"
          :params="{
            animateDuration: 0.5,
            animateType: 'waveSmall',
            txtStyle: {
              lineHeight: 2,
              fontSize: '16px',
              color: 'hsla(0,0%,100%,.6)'
            }
          }"
        />
        <span class="bottom-line" ref="bottom-line"></span>
        <span class="left-dot" ref="left-dot"></span>
      </div>
      <span class="video-1" ref="video1"></span>
      <span class="video-2" ref="video2"></span>
      <span class="close din" ref="close" @click="clickClose">关闭</span>
    </div>
  </div>
</template>
<script>
import txt from './txt'
import { Howl } from 'howler'
import { mapState, mapMutations } from 'vuex'
export default {
  name: 'poppup',
  components: { txt },
  computed: {
    ...mapState('focus', ['carousel']),
    desShow() {
      return this.param.title || this.param.describe
    },
    scaleFun() {
      let content = this.param.content
      let h = app.anovPart[content]['anovPart']['style']['height']
      let w = app.anovPart[content]['anovPart']['style']['width']

      let parent = this.$refs.content
      let ph = window.getComputedStyle(parent).height
      let pw = window.getComputedStyle(parent).width

      let scale =
        Math.floor(
          Math.min(parseInt(ph) / parseInt(h), parseInt(pw) / parseInt(w)) * 100
        ) / 100

      return `transform:scale(${scale});width:${w};height:${h};`
    }
  },
  props: ['param'],
  data() {
    return {
      describe: '',
      title: '',
      num: 0,
      player: null,
      audioUrl: '',
      sound: null,
      videoShow: false,
      isImage: false,
      isVideo: false,
      isComp: false,
      muted: false,
      timer: null
    }
  },
  mounted() {},
  methods: {
    ...mapMutations('focus', ['setCarousel']),
    show() {
      //监听路由切换，取消聚焦操作
      app.$on(app.EventType.pageLeave, this.pageLeave)
      if (this.videoShow) return
      let opt = {}
      Object.assign(opt, this.param)
      this.videoShow = true
      this.num++
      this.$refs['popup'].style.display = 'block'
      this.describe = opt.describe
      this.title = opt.title
      this.audioUrl = opt.audioUrl
      this.content = opt.content
      this.isImage = /\.(png|jpg|gif|jpeg|webp)$/.test(this.content)
      this.isVideo = /\.mp4$/.test(this.content)
      // 判断是否需要旁白解说，不需要时自动播放视频原声
      this.videoSoundtrack = opt.videoSoundtrack
      if (this.isImage) {
        //图片
        this.isVideo = false
        this.isComp = false
      } else if (this.isVideo) {
        this.isImage = false
        this.isComp = false
        //视频
      } else {
        this.isComp = true
        this.isImage = false
        this.isVideo = false
      }
      if (!this.videoSoundtrack && this.audioUrl) {
        this.muted = true
        this.sound = new Howl({
          src: this.audioUrl,
          loop: true,
          html5: true,
          volume: 0.2
        })
        this.player = this.sound.play()
        if (app.voiceFeedbackServer.state == false) {
          this.sound.fade(this.sound.volume(), 1, 2000)
        }
      } else {
        this.muted = false
      }
      // 是否自动轮播
      if (this.carousel) {
        this.bindEvent()
      }
      // ----------------------------
      if (this.tl) this.tl = null
      this.tl = new TimelineMax({})
      let mask = TweenMax.to(this.$refs['mask'], 0.5, { opacity: 1 })
      let popWrapper = TweenMax.to(this.$refs['popWrapper'], 0.3, {
        opacity: 1,
        height: 689
      })
      let rect1 = TweenMax.from(this.$refs['rect2'], 1.5, {
        drawSVG: '100% 100%'
      })
      let rect2 = TweenMax.from(this.$refs['rect1'], 1.5, {
        drawSVG: '100% 100%'
      })
      let content = TweenMax.to(this.$refs['content'], 0.5, { opacity: 1 })
      let video1 = TweenMax.to(this.$refs['video1'], 0.5, {
        opacity: 1,
        x: '-=50',
        ease: Expo.easeInOut
      })
      let video2 = TweenMax.to(this.$refs['video2'], 0.5, {
        opacity: 1,
        x: '+=100',
        ease: Expo.easeInOut
      })
      let close = TweenMax.to(this.$refs['close'], 0.5, {
        opacity: 1,
        x: '-=100',
        ease: Expo.easeInOut
      })
      this.$nextTick(() => {
        this.isVideo && this.$refs['player'].play()

        this.tl
          .addLabel('start', 0)
          .add(mask, 'start+=0.1')
          .add(popWrapper, 'start+=0.2')
          .add(rect1, 'start+=0.2')
          .add(rect2, 'start+=0.4')
          .add(content, 'start+=0.6')
          .add(close, 'start+=0.8')
          .add(video1, 'start+=0.6')
          .add(video2, 'start+=0.8')
          .add(() => {
            if (this.isComp && !this.tl.reversed()) {
              this.$refs.popupComponent.init()
            }
          }, 'start+=0.6')
          .add(() => {
            if (this.tl?.reversed()) return
            if (this.videoSoundtrack) return
            if (!(this.title || this.describe)) return
            app.voiceFeedbackServer.speak(this.title + '    ' + this.describe)
            if (app.voiceFeedbackServer.state == true) {
              app.voiceFeedbackServer.addEventListener('end', this.soundEvent)
              this.isBindEvent = true
            }
          }, 'start+=0.3')
          if (this.param.title) {
            let bottomLine = TweenMax.to(this.$refs['bottom-line'], 0.5, {
              width: 254,
              ease: Expo.easeInOut
            })
            let leftDot = TweenMax.to(this.$refs['left-dot'], 0.3, { opacity: 1 })
            this.tl
              .add(this.$refs.title.init(), 'start+=0.8')
              .add(leftDot, 'start+=0.9')
              .add(bottomLine, 'start+=0.9')
          }
          if (this.param.describe) {
            let describe = this.$refs.describe.init()
            describe.timeScale(2)
            describe.eventCallback('onComplete', () => {
              describe.timeScale(5)
            })
            this.tl.add(describe, 'start+=1')
          }
      })
    },
    hide() {
      if (this.timer) clearTimeout(this.timer)
      this.muted = true
      this.videoShow = false
      if (app.voiceFeedbackServer.state == true && this.isBindEvent == true) {
        app.voiceFeedbackServer.synthesis.cancel()
        app.voiceFeedbackServer.removeEventListener('end', this.soundEvent)
      }
      this.sound?.fade(this.sound.volume(), 0, 2000)
      if (!this.tl) return
      this.tl.eventCallback('onReverseComplete', () => {
        this.sound?.unload()
        this.sound = null
        if (this.isVideo) {
          this.$refs['player'].currentTime = 0
        }
        this.tl.clear()
        this.tl.eventCallback('onReverseComplete', null)
        this.tl = null
        this.$refs['popup'].style.display = 'none'
        this.$refs.rect1.style['stroke-dashoffset'] = '0px'
        this.$refs.rect1.style['stroke-dasharray'] = 'none'
        this.$refs.rect2.style['stroke-dashoffset'] = '0px'
        this.$refs.rect2.style['stroke-dasharray'] = 'none'
        this.isComp = false
        this.isImage = false
        this.isVideo = false
        app.focusServer.hideComplete()
        app.$off(app.EventType.pageLeave, this.pageLeave)
        // 自动轮播时 通知系统播放下一个
        if (this.carousel) {
          app.focusServer.focuseNext()
        }
      })
      this.tl?.timeScale(3).reverse()
    },
    pageLeave() {
      app.focusServer.inactivated()
      app.focusServer.carousel = false
    },
    soundEvent() {
      this.sound?.fade(this.sound.volume(), 1, 2000)
    },
    clickClose() {
      this.carousel && this.setCarousel(false)
      app.focusServer.inactivated()
    },
    // 自动轮播时当前模块结束
    endEvent() {
      if (this.timer) {
        clearTimeout(this.timer)
        this.timer = null
      }
      if (this.video) {
        this.video.loop = true
        this.video.removeEventListener('ended', this.nextEvent)
      }
      // 通知系统当前轮播组件结束
      app.focusServer.inactivated()
    },
    // 自动轮播事件
    bindEvent() {
      this.$nextTick(() => {
        // 视频时 默认视频结束 当前模块展示结束
        if (this.isVideo) {
          this.video = document.getElementById('video-player')
          this.video.loop = false
          this.video.addEventListener('ended', this.endEvent)
        }
        // 图片时 设定当前图片展示事件
        if (this.isImage) {
          this.timer = setTimeout(() => {
            this.endEvent()
          }, 15000)
        }
        // 组件时 设定当前组件展时间
        if (this.isComp) {
          this.timer = setTimeout(() => {
            this.endEvent()
          }, 15000)
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.pop-wrapper {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  z-index: 1000;
  display: none;
  pointer-events: all;
  transform: scale(1.22) !important;
  transform-origin: center !important;
}
.mask {
  opacity: 0;
  position: absolute;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(10px);
}
.pop-wrapper-content {
  position: absolute;
  width: 1558px;
  height: 0;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  justify-content: space-between;
  align-items: center;
  opacity: 0;
  padding: 0 50px;
}
.content-noDes {
  justify-content: center;
}
.close {
  position: absolute;
  width: 208px;
  height: 50px;
  cursor: pointer;
  background: url('../../../../../../../assets/imgs/sys-img/focus/close.png')
    no-repeat;
  background-size: contain;
  right: -101px;
  top: -80px;
  text-align: center;
  line-height: 50px;
  text-indent: 90px;
  font-size: 20px;
  color: #50f2f2;
  font-weight: 700;
  letter-spacing: 2px;
  opacity: 0;
  pointer-events: all;
}
.video-1 {
  position: absolute;
  width: 24px;
  height: 214px;
  background: url('../../../../../../../assets/imgs/sys-img/focus/video-1.png')
    no-repeat;
  background-size: cover;
  right: -30px;
  bottom: -11px;
  opacity: 0;
}
.video-2 {
  position: absolute;
  width: 353px;
  height: 51px;
  background: url('../../../../../../../assets/imgs/sys-img/focus/video-2.png')
    no-repeat;
  background-size: cover;
  left: -101px;
  bottom: -81px;
  opacity: 0;
}
.player-wrapper {
  position: relative;
  width: 1144px;
  height: 645px;
  // top: 218px;
  // left: 237px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background-size: contain;
  opacity: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  video,
  .content {
    width: 100%;
    height: 100%;
    outline: none;
  }
}
.no-border {
  border: none;
}
.describe {
  position: relative;
  width: 284px;
  height: 625px;
  // right: 237px;
  // top: 238px;
  padding: 15px;
}
.title {
  display: inline-block;
  width: 100%;
  height: 50px;
  line-height: 50px;
  font-size: 18px;
  margin-bottom: 25px;
}
.left-dot {
  position: absolute;
  width: 4px;
  height: 4px;
  background: rgba(80, 242, 242, 1);
  right: 283px;
  top: 37px;
  opacity: 0;
}
.bottom-line {
  position: absolute;
  height: 2px;
  background: linear-gradient(to right, rgba(80, 242, 242, 0.7), transparent);
  top: 65px;
  right: 16px;
}
svg {
  position: absolute;
  width: 1562px;
  height: 752px;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.st0 {
  fill: #000000b3;
  stroke: #50f2f2;
  stroke-width: 3;
}
.st1 {
  fill: none;
  stroke: #50f2f2;
  stroke-width: 2;
  opacity: 0.3;
}
</style>
